home *** CD-ROM | disk | FTP | other *** search
/ Libris Britannia 4 / science library(b).zip / science library(b) / DJGPP / GCC257S5.ZIP / src / gcc-257 / objc / object.m < prev    next >
Text File  |  1993-09-22  |  8KB  |  377 lines

  1. /* The implementation of class Object for Objective-C.
  2.    Copyright (C) 1993 Free Software Foundation, Inc.
  3.  
  4. This file is part of GNU CC.
  5.  
  6. GNU CC is free software; you can redistribute it and/or modify it
  7. under the terms of the GNU General Public License as published by the
  8. Free Software Foundation; either version 2, or (at your option) any
  9. later version.
  10.  
  11. GNU CC is distributed in the hope that it will be useful, but WITHOUT
  12. ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  13. or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
  14. License for more details.
  15.  
  16. You should have received a copy of the GNU General Public License
  17. along with GNU CC; see the file COPYING.  If not, write to
  18. the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
  19.  
  20. /* As a special exception, if you link this library with files compiled
  21.    with GCC to produce an executable, this does not cause the resulting
  22.    executable to be covered by the GNU General Public License.  This
  23.    exception does not however invalidate any other reasons why the
  24.    executable file might be covered by the GNU General Public License. */
  25.  
  26. #include "objc/Object.h"
  27. #include "objc/Protocol.h"
  28. #include "objc/objc-api.h"
  29.  
  30. #include "gstdarg.h"
  31. extern void (*_objc_error)(id object, const char *format, va_list);
  32.  
  33. extern int errno;
  34.  
  35. #define MAX_CLASS_NAME_LEN 256
  36.  
  37. @implementation Object
  38.  
  39. + initialize
  40. {
  41.   return self;
  42. }
  43.  
  44. - init
  45. {
  46.   return self;
  47. }
  48.  
  49. + new
  50. {
  51.   return [[self alloc] init];
  52. }
  53.  
  54. + alloc
  55. {
  56.   return class_create_instance(self);
  57. }
  58.  
  59. - free
  60. {
  61.   return object_dispose(self);
  62. }
  63.  
  64. - copy
  65. {
  66.   return [[self shallowCopy] deepen];
  67. }
  68.  
  69. - shallowCopy
  70. {
  71.   return object_copy(self);
  72. }
  73.  
  74. - deepen
  75. {
  76.   return self;
  77. }
  78.  
  79. - deepCopy
  80. {
  81.   return [self copy];
  82. }
  83.  
  84. - (Class*)class
  85. {
  86.   return object_get_class(self);
  87. }
  88.  
  89. - (Class*)superClass
  90. {
  91.   return object_get_super_class(self);
  92. }
  93.  
  94. - (MetaClass*)metaClass
  95. {
  96.   return object_get_meta_class(self);
  97. }
  98.  
  99. - (const char *)name
  100. {
  101.   return object_get_class_name(self);
  102. }
  103.  
  104. - self
  105. {
  106.   return self;
  107. }
  108.  
  109. - (unsigned int)hash
  110. {
  111.   return (size_t)self;
  112. }
  113.  
  114. - (BOOL)isEqual:anObject
  115. {
  116.   return self==anObject;
  117. }
  118.  
  119. - (int)compare:anotherObject;
  120. {
  121.   if ([self isEqual:anotherObject])
  122.     return 0;
  123.   // Ordering objects by their address is pretty useless, 
  124.   // so subclasses should override this is some useful way.
  125.   else if (self > anotherObject)
  126.     return 1;
  127.   else 
  128.     return -1;
  129. }
  130.  
  131. - (BOOL)isMetaClass
  132. {
  133.   return NO;
  134. }
  135.  
  136. - (BOOL)isClass
  137. {
  138.   return object_is_class(self);
  139. }
  140.  
  141. - (BOOL)isInstance
  142. {
  143.   return object_is_instance(self);
  144. }
  145.  
  146. - (BOOL)isKindOf:(Class*)aClassObject
  147. {
  148.   Class* class;
  149.  
  150.   for (class = self->isa; class!=Nil; class = class_get_super_class(class))
  151.     if (class==aClassObject)
  152.       return YES;
  153.   return NO;
  154. }
  155.  
  156. - (BOOL)isMemberOf:(Class*)aClassObject
  157. {
  158.   return self->isa==aClassObject;
  159. }
  160.  
  161. - (BOOL)isKindOfClassNamed:(const char *)aClassName
  162. {
  163.   Class* class;
  164.  
  165.   if (aClassName!=NULL)
  166.     for (class = self->isa; class!=Nil; class = class_get_super_class(class))
  167.       if (!strcmp(class_get_class_name(class), aClassName))
  168.         return YES;
  169.   return NO;
  170. }
  171.  
  172. - (BOOL)isMemberOfClassNamed:(const char *)aClassName
  173. {
  174.   return ((aClassName!=NULL)
  175.           &&!strcmp(class_get_class_name(self->isa), aClassName));
  176. }
  177.  
  178. + (BOOL)instancesRespondTo:(SEL)aSel
  179. {
  180.   return class_get_instance_method(self, aSel)!=METHOD_NULL;
  181. }
  182.  
  183. - (BOOL)respondsTo:(SEL)aSel
  184. {
  185.   return ((object_is_instance(self)
  186.            ?class_get_instance_method(self->isa, aSel)
  187.            :class_get_class_method(self->isa, aSel))!=METHOD_NULL);
  188. }
  189.  
  190. + (IMP)instanceMethodFor:(SEL)aSel
  191. {
  192.   return method_get_imp(class_get_instance_method(self, aSel));
  193. }
  194.  
  195. // Indicates if the receiving class or instance conforms to the given protocol
  196. // not usually overridden by subclasses
  197. - (BOOL) conformsTo: (Protocol*)aProtocol
  198. {
  199.   int i;
  200.   struct objc_protocol_list* proto_list;
  201.  
  202.   for (proto_list = isa->protocols;
  203.        proto_list; proto_list = proto_list->next)
  204.     {
  205.       for (i=0; i < proto_list->count; i++)
  206.       {
  207.         if ([proto_list->list[i] conformsTo: aProtocol])
  208.           return YES;
  209.       }
  210.     }
  211.  
  212.   if ([self superClass])
  213.     return [[self superClass] conformsTo: aProtocol];
  214.   else
  215.     return NO;
  216. }
  217.  
  218. - (IMP)methodFor:(SEL)aSel
  219. {
  220.   return (method_get_imp(object_is_instance(self)
  221.                          ?class_get_instance_method(self->isa, aSel)
  222.                          :class_get_class_method(self->isa, aSel)));
  223. }
  224.  
  225. + (struct objc_method_description *)descriptionForInstanceMethod:(SEL)aSel
  226. {
  227.   return ((struct objc_method_description *)
  228.            class_get_instance_method(self, aSel));
  229. }
  230.  
  231. - (struct objc_method_description *)descriptionForMethod:(SEL)aSel
  232. {
  233.   return ((struct objc_method_description *)
  234.            (object_is_instance(self)
  235.             ?class_get_instance_method(self->isa, aSel)
  236.             :class_get_class_method(self->isa, aSel)));
  237. }
  238.  
  239. - perform:(SEL)aSel
  240. {
  241.   IMP msg = objc_msg_lookup(self, aSel);
  242.   if (!msg)
  243.     return [self error:"invalid selector passed to %s", sel_get_name(_cmd)];
  244.   return (*msg)(self, aSel);
  245. }
  246.  
  247. - perform:(SEL)aSel with:anObject
  248. {
  249.   IMP msg = objc_msg_lookup(self, aSel);
  250.   if (!msg)
  251.     return [self error:"invalid selector passed to %s", sel_get_name(_cmd)];
  252.   return (*msg)(self, aSel, anObject);
  253. }
  254.  
  255. - perform:(SEL)aSel with:anObject1 with:anObject2
  256. {
  257.   IMP msg = objc_msg_lookup(self, aSel);
  258.   if (!msg)
  259.     return [self error:"invalid selector passed to %s", sel_get_name(_cmd)];
  260.   return (*msg)(self, aSel, anObject1, anObject2);
  261. }
  262.  
  263. - forward:(SEL)aSel :(arglist_t)argFrame
  264. {
  265.   return [self doesNotRecognize: aSel];
  266. }
  267.  
  268. - performv:(SEL)aSel :(arglist_t)argFrame
  269. {
  270.   return objc_msg_sendv(self, aSel, argFrame);
  271. }
  272.  
  273. + poseAs:(Class*)aClassObject
  274. {
  275.   return class_pose_as(self, aClassObject);
  276. }
  277.  
  278. - (Class*)transmuteClassTo:(Class*)aClassObject
  279. {
  280.   if (object_is_instance(self))
  281.     if (class_is_class(aClassObject))
  282.       if (class_get_instance_size(aClassObject)==class_get_instance_size(isa))
  283.         if ([self isKindOf:aClassObject])
  284.           {
  285.             Class* old_isa = isa;
  286.             isa = aClassObject;
  287.             return old_isa;
  288.           }
  289.   return nil;
  290. }
  291.  
  292. - subclassResponsibility:(SEL)aSel
  293. {
  294.   return [self error:"subclass should override %s", sel_get_name(aSel)];
  295. }
  296.  
  297. - notImplemented:(SEL)aSel
  298. {
  299.   return [self error:"method %s not implemented", sel_get_name(aSel)];
  300. }
  301.  
  302. - shouldNotImplement:(SEL)aSel
  303. {
  304.   return [self error:"%s should not implement %s", 
  305.                  object_get_class_name(self), sel_get_name(aSel)];
  306. }
  307.  
  308. - doesNotRecognize:(SEL)aSel
  309. {
  310.   return [self error:"%s does not recognize %s",
  311.                      object_get_class_name(self), sel_get_name(aSel)];
  312. }
  313.  
  314. - error:(const char *)aString, ...
  315. {
  316. #define FMT "error: %s (%s)\n%s\n"
  317.   char fmt[(strlen((char*)FMT)+strlen((char*)object_get_class_name(self))
  318.             +((aString!=NULL)?strlen((char*)aString):0)+8)];
  319.   va_list ap;
  320.  
  321.   sprintf(fmt, FMT, object_get_class_name(self),
  322.                     object_is_instance(self)?"instance":"class",
  323.                     (aString!=NULL)?aString:"");
  324.   va_start(ap, aString);
  325.   (*_objc_error)(self, fmt, ap);
  326.   va_end(ap);
  327.   return nil;
  328. #undef FMT
  329. }
  330.  
  331. + (int)version
  332. {
  333.   return class_get_version(self);
  334. }
  335.  
  336. + setVersion:(int)aVersion
  337. {
  338.   class_set_version(self, aVersion);
  339.   return self;
  340. }
  341.  
  342. + (int)streamVersion: (TypedStream*)aStream
  343. {
  344. #ifndef __alpha__
  345.   if (aStream->mode == OBJC_READONLY)
  346.     return objc_get_stream_class_version (aStream, self);
  347.   else
  348. #endif
  349.     return class_get_version (self);
  350. }
  351.  
  352. // These are used to write or read the instance variables 
  353. // declared in this particular part of the object.  Subclasses
  354. // should extend these, by calling [super read/write: aStream]
  355. // before doing their own archiving.  These methods are private, in
  356. // the sense that they should only be called from subclasses.
  357.  
  358. - read: (TypedStream*)aStream
  359. {
  360.   // [super read: aStream];  
  361.   return self;
  362. }
  363.  
  364. - write: (TypedStream*)aStream
  365. {
  366.   // [super write: aStream];
  367.   return self;
  368. }
  369.  
  370. - awake
  371. {
  372.   // [super awake];
  373.   return self;
  374. }
  375.  
  376. @end
  377.